import argparse
import os
import sys


# 假设的函数实现
def printCookies(cookiesDB):
    try:
        conn = sqlite3.connect(cookiesDB)
        c = conn.cursor()
        c.execute('SELECT host, name, value FROM moz_cookies')
        print('\n[*] -- Found Cookies --')
        for row in c.fetchall():
            host = str(row[0])
            name = str(row[1])
            value = str(row[2])
            # 注意在 Host 和 host 之间，以及 Cookie 和 name 之间添加了空格
            print('[+] Host: ' + host + ', Cookie: ' + name + ', Value: ' + value)
    except Exception as e:
        if 'encrypted' in str(e):
            print('\n[*] Error reading your cookies database.')
            print('[*] Upgrade your Python-Sqlite3 Library or check your database path.')
        else:
            # 打印出具体的错误信息，以便调试
            print(f'\n[*] An error occurred: {e}')

        # 注意确保文件路径是正确的，并且 Firefox 没有在运行时锁定该数据库



def printCookies(cookiesDB):
    try:
        conn = sqlite3.connect(cookiesDB)
        c = conn.cursor()
        c.execute('SELECT host, name, value FROM moz_cookies')
        print('\n[*] -- Found Cookies --')
        for row in c.fetchall():
            host = str(row[0])
            name = str(row[1])
            value = str(row[2])
            # 注意在 Host 和 host 之间，以及 Cookie 和 name 之间添加了空格
            print('[+] Host: ' + host + ', Cookie: ' + name + ', Value: ' + value)
    except Exception as e:
        if 'encrypted' in str(e):
            print('\n[*] Error reading your cookies database.')
            print('[*] Upgrade your Python-Sqlite3 Library or check your database path.')
        else:
            # 打印出具体的错误信息，以便调试
            print(f'\n[*] An error occurred: {e}')

        # 注意确保文件路径是正确的，并且 Firefox 没有在运行时锁定该数据库


def printGoogle(placesDB):
    try:
        conn = sqlite3.connect(placesDB)
        c = conn.cursor()
        # 使用三引号来包含整个 SQL 查询，并修正字段名（应该是 'url' 而不是 'ur1'）
        c.execute("""  
            SELECT url, datetime(visit_date/1000000, 'unixepoch') AS visit_date  
            FROM moz_places  
            JOIN moz_historyvisits ON moz_places.id = moz_historyvisits.place_id  
            WHERE visit_count > 0;  
        """)
        print('\n[*] -- Found Google History --')
        for row in c.fetchall():
            url = row[0]
            date = row[1]
            # 检查 URL 是否包含 'google'（不区分大小写）
            if 'google' in url.lower():
                print(f'[+] Visited Google URL: {url} on {date}')
    except Exception as e:
        # 改进错误消息，明确指出可能是数据库路径问题或加密问题
        if 'encrypted' in str(e):
            print('\n[*] Error reading your places database. The database may be encrypted.')
            print('[*] Ensure your database path is correct and you have the necessary decryption tools.')
        else:
            # 对于其他类型的错误，打印出具体的错误信息
            print(f'\n[*] An error occurred: {e}')
            print('[*] Check your database path and permissions.')
    finally:
        # 无论是否发生异常，都关闭数据库连接
        conn.close()

    # 调用函数，确保文件路径正确


def main():
    parser = argparse.ArgumentParser("usage: %prog -p <firefox profilepath>")
    parser.add_argument("-p", dest="pathname", type=str,
                        help="specify firefox profile path")
    options = parser.parse_args()  # 只接收一个返回值
    pathName = options.pathname

    if pathName is None:
        print(parser.usage)
        sys.exit(1)  # 使用非零退出码表示错误

    if not os.path.isdir(pathName):
        print('[!] Path Does Not Exist:', pathName)
        sys.exit(1)

    cookieDB = os.path.join(pathName, r"C:\Users\yangchen\AppData\Roaming\Mozilla\Firefox\Profiles\lkcrh8j5.default-release\cookies.sqlite")
    if os.path.isfile(cookieDB):
        printCookies(cookieDB)
    else:
        print('[!] No cookies.sqlite file found in', pathName)

    placesDB = os.path.join(pathName, r"C:\Users\yangchen\AppData\Roaming\Mozilla\Firefox\Profiles\lkcrh8j5.default-release\places.sqlite")
    if os.path.isfile(placesDB):
        printPlaces(placesDB)
        printGoogle(placesDB)
    else:
        print('[!] No places.sqlite file found in', pathName)


if __name__ == "__main__":
    main()